﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Xml.Linq;
using EzDesk.Clients.Utility;
using EzDesk.DevHelper.FeedStudio.Model;
using EzDesk.DevHelper.FeedStudio.Presenter;
using EzDesk.Utility.Json;
using EzDesk.Utility.Log;


namespace EzDesk.DevHelper.FeedStudio.Views
{
    public partial class FeedForm : Form, IFeedView
    {
        private FeedPresenter _feedPresenter;
        private FeedMainPresenter _mainPresenter;

        private Dictionary<string, string> parameters = new Dictionary<string, string>();
        private bool _isLoaded;
        private bool _isEdited;
        private string _feedName;
        private int originalWidth;
        private WpfPreviewPresenter _wpfPreviewPresenter;

        public FeedForm(string feedName, FeedMainPresenter mainPresenter)
        {
            _isLoaded = false;
            _isEdited = false;


            InitializeComponent();
            _feedPresenter = new FeedPresenter(this);

            setDateSourceOfComBox();

            _feedName = feedName;
            _mainPresenter = mainPresenter;

            setBtnSaveEnabled();
            closeEditDataPanel();


            originalWidth = Width;

            ShowWPFPreview();
            _feedPresenter.GetFeedInfo(_feedName);

            _isLoaded = true;
        }

        private void ShowWPFPreview()
        {
            this._wpfPreviewPresenter = new WpfPreviewPresenter(new WpfPreview());
            _wpfPreviewPresenter.View.Show();
            this.Closing += (o, e) => {
                _wpfPreviewPresenter.View.Close();
                _wpfPreviewPresenter.View = null;
                _wpfPreviewPresenter = null;
            };
        }

        private void closeEditDataPanel()
        {
            pnFeedData.Hide();
        }


        //设置typeComBox的值
        private void setDateSourceOfComBox()
        {
            cmBoxType.DisplayMember = "Text";
            cmBoxType.ValueMember = "Value";
            cmBoxType.DataSource = new ArrayList()
                                       {
                                           new { Text = "Update", Value = 0 },
                                           new { Text = "Notification", Value = 1 },
                                           new { Text = "ToDoItem", Value = 2 },
                                       };
        }


        public bool IsError
        {
            set
            {
                pnIsError.BackColor = value ? Color.Red : Color.Green;
            }
        }



        public void DisplayFeedInfo(dynamic feedInfo)
        {
            SetFormTitle(feedInfo.TemplateName);
            DisplayFeedItem(feedInfo);
            refreshFeedData();
            PreviewFeedInfo();
        }

        private void SetFormTitle(string templateName)
        {
            Text = "编辑: " + templateName;
        }


        private void DisplayFeedItem(dynamic feedInfo)
        {
            var iconUrl = string.IsNullOrEmpty(feedInfo.Icon) ? "NoIcon" : feedInfo.Icon.ToString();

            txtFeedTemp.Text = feedInfo.TemplateName;
            txtTitle.Text = feedInfo.Title;
            txtBody.Text = feedInfo.Body;
            txtId.Text = feedInfo.TempleId.ToString();
            txtIcon.Text = iconUrl;
            cmBoxType.SelectedValue = feedInfo.Type;
        }




        private void refreshFeedData()
        {
            string content = txtTitle.Text + txtBody.Text;
            Regex regex = new Regex(
                @"(?<={)\w+(?=})",
                RegexOptions.IgnoreCase | RegexOptions.Compiled
                );

            MatchCollection feedDateMatchs = regex.Matches(content);
            IList<string> mathes = 
                (from object match in feedDateMatchs
                 select match.ToString())
                .ToList();

            var parameterNotExists = parameters
                .Where(parameter => !mathes.Contains(parameter.Key))
                .ToList();

            foreach (var p in parameterNotExists)
            {
                parameters.Remove(p.Key);
            }

            foreach (var match in mathes)
            {
                if (!parameters.ContainsKey(match))
                {
                    string feedDataReplced = getFeedInfoReplaced(match);
                    parameters.Add(match, feedDataReplced);
                }
            }

            refreshFeedDataList();
        }





        private string getFeedInfoReplaced(string feedData)
        {
            string feedDataReplaced = "helloWord";
            switch (feedData)
            {   //messageFeedTemplate
                case "senderName":
                    feedDataReplaced = "Bowen";
                    break;
                case "messageName":
                    feedDataReplaced = "WCF技术";
                    break;
                case "messageText":
                    feedDataReplaced = "WCF核心技术是一本很NB的书！";
                    break;
                case "messageSummary":
                    feedDataReplaced = "WCF核心技术";
                    break;
                case "replyCount":
                    feedDataReplaced = "9";
                    break;
                case "confirmCount":
                    feedDataReplaced = "10";
                    break;
                case "senderId":
                    feedDataReplaced = Guid.NewGuid().ToString();
                    break;
                case "messageId":
                    feedDataReplaced = Guid.NewGuid().ToString();
                    break;
                //attendanceTemplate

            }
            return feedDataReplaced;
        }



        private void refreshFeedDataList()
        {
            lstFeedData.DataSource = null;

            var dataList = new List<KeyValueItem>();

            foreach (var keyValuePair in parameters)
            {
                dataList.Add(
                    new KeyValueItem()
                    {
                        Text = string.Format("{0} : {1}", keyValuePair.Key, keyValuePair.Value),
                        Value = keyValuePair.Key
                    }
                    );
            }

            lstFeedData.DisplayMember = "Text";
            lstFeedData.ValueMember = "Value";
            lstFeedData.DataSource = dataList;

        }




        public void PreviewFeedInfo()
        {
            if (chkPreview.Checked)
            {
                enablePreviewPanel();
                previewHtmlFeed();
                previewHtmlPageFeed();
                previewWPFFeed();


            }else
            {
                disablePreviewPanel();
            }
        }

        private void previewWPFFeed()
        {
            var contentStr = string.Format("<root>{0}{1}</root>", this.txtTitle.Text, this.txtBody.Text);
            contentStr = Helper.MergeDataToEzML(contentStr, parameters); 
            this._wpfPreviewPresenter.Preview(contentStr);
        }

        private void enablePreviewPanel()
        {
            Width = originalWidth;
            pnlFeedPreview.Visible = true;
        }

        private void disablePreviewPanel()
        {
            Width = originalWidth - +pnlFeedPreview.Width;
            pnlFeedPreview.Visible = false;
        }


        private void previewHtmlFeed()
        {
            string templeId = txtId.Text;
            string feedTitle = Helper.MergeDataToEzML(txtTitle.Text, parameters);
            string feedBody = Helper.MergeDataToEzML(txtBody.Text, parameters);
            string feedType = cmBoxType.Text;

            // 生成FeedXml
            string feedXml = generationFeedXml(templeId, feedType, feedTitle, feedBody, parameters);

            FeedCollection feedCollection;
            try
            {
                feedCollection = FeedCollection.Create(feedXml);
            }
            catch (Exception ex)
            {
                IsError = true;
                return;
            }
            btnEditData.Text = feedCollection[0].TransformedData.ToString();

            IsError = false;
        }



        private void previewHtmlPageFeed()
        {
            string feedHtml;
            string feedType = cmBoxType.SelectedValue.ToString();

            //  生成Html预览
            using (var sr = new StreamReader("../../ez-sample.htm"))
            {
                feedHtml = sr.ReadToEnd();

                if (feedType == "1")
                {
                    // notification
                    feedHtml = feedHtml.Replace("{notificationHtml}", btnEditData.Text);
                }
                if (feedType == "0")
                {
                    // update
                    feedHtml = feedHtml.Replace("{UpdateHtml}", btnEditData.Text);
                }
                if (feedType == "2")
                {
                    // todoItem
                    feedHtml = feedHtml.Replace("{TodoItem}", btnEditData.Text);
                }
            }

            webBrowser1.DocumentText = feedHtml;
        }



        private void setBtnSaveEnabled()
        {
            btnSave.Enabled = _isEdited;
        }






        private void btnSave_Click(object sender, EventArgs e)
        {
            dynamic feedInfo = new
                                   {
                                       TemplateName = txtFeedTemp.Text,
                                       Title = txtTitle.Text,
                                       Body = txtBody.Text,
                                       TempleId = new Guid(txtId.Text),
                                       Type = cmBoxType.SelectedValue,
                                       TemplateIcon = txtIcon.Text
            };

            _feedPresenter.UpdateTestList(feedInfo);

            //mainView刷新feed列表
            _mainPresenter.RefreshFeedList();

            MessageBox.Show("保存成功！");
        }



        private void txtFeedData_Changed(object sender, EventArgs e)
        {
            if (_isLoaded)
            {
                _isEdited = true;
                refreshFeedData();
                PreviewFeedInfo();
            }

            setBtnSaveEnabled();
        }



        private void btnEdit_Click(object sender, EventArgs e)
        {
            string feedEdited = txtFeedDataValue.Text;
            parameters[txtFeedDataText.Text] = feedEdited;
            refreshFeedData();

            PreviewFeedInfo();

            closeEditDataPanel();
        }


        private void btnReset_Click(object sender, EventArgs e)
        {
            _feedPresenter.GetFeedInfo(_feedName);
            _isEdited = false;
            setBtnSaveEnabled();
        }


        private void lstFeedData_DoubleClick(object sender, EventArgs e)
        {
            if (lstFeedData.SelectedItems.Count == 1)
            {
                pnFeedData.Show();

                txtFeedDataText.Text = lstFeedData.SelectedValue.ToString();
                txtFeedDataValue.Text = parameters[lstFeedData.SelectedValue as string];
            }
        }




        private void btnCancleEditData_Click(object sender, EventArgs e)
        {
            closeEditDataPanel();
        }


        //todo..
        //重构
        private string generationFeedXml(string txtId, 
            string txtType, 
            string feedTitle,string feedBody,
            Dictionary<string, string> parameters)
        {
            XElement feedItems = new XElement("feeditems");

            XElement root = new XElement("root");
            root.Add(new XAttribute("appportalurl", "http://localhost:19145"));
            root.Add(feedItems);

            int count = 0;
            string feedDataStr = JsonHelper.ConvertToJson(parameters);

            XElement feedItem = new XElement("feeditem");
            feedItem.Add(new XAttribute("guid", txtId));
            feedItem.Add(new XAttribute("createon", DateTime.Now.ToString()));
            feedItem.Add(new XAttribute("updateon", DateTime.Now.ToString()));
            feedItem.Add(new XAttribute("lastchangeon", DateTime.Now.ToString()));
            feedItem.Add(new XAttribute("isavailable", true));
            feedItem.Add(new XAttribute("isread", false));
            feedItem.Add(new XAttribute("ismark", false));
            feedItem.Add(new XAttribute("type", txtType));
            feedItem.Add(new XAttribute("iconurl", "default.png"));

            feedItem.Add(new XElement("data", new XCData(feedDataStr)));

            feedItem.Add(new XElement("title", new XCData(feedTitle)));
            feedItem.Add(new XElement("body", new XCData(feedBody)));

            feedItems.Add(feedItem);
            count++;


            feedItems.Add(new XAttribute("count", count));

            return root.ToString();
        }

        private void chkBox_CheckedChanged(object sender, EventArgs e)
        {
            PreviewFeedInfo();
        }

        private void btnRefreshPreview_Click(object sender, EventArgs e)
        {
            PreviewFeedInfo();
        }

        private void btnEditBody_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            LogEx.TRACE("Form", "开始编辑 Body");

            SetEditButtonsEnabled(false);
            EzMLForm editForm = new EzMLForm("body", txtBody.Text, this);
            editForm.Show();

            editForm.Location = btnEditBody.Location;
        }

        private void btnEditTitle_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            LogEx.TRACE("Form", "开始编辑 Title");

            SetEditButtonsEnabled(false);
            EzMLForm editForm = new EzMLForm("title", txtTitle.Text, this);
            editForm.Show();
            editForm.Location = btnEditTitle.Location;
        }

        public void SetEditButtonsEnabled(bool enabled)
        {
            btnEditBody.Enabled = enabled;
            btnEditTitle.Enabled = enabled;
        }

        public void ChangeFeedTitle(string titleContent)
        {
            txtTitle.Text = titleContent;
        }

        public void ChangeFeedBody(string bodyContent)
        {
            txtBody.Text = bodyContent;
        }

        private void pnlFeedPreview_Paint(object sender, PaintEventArgs e)
        {
             
        }
    }
}
